#include<iostream>

using namespace std;
const int N =50010;
 
int p[N]={0},dis[N]={0};
int n,k,ans=0;

int find(int x) {
    if (x != p[x]) {
        int t = p[x]; // 记录父节点
        p[x] = find(p[x]); // 路径压缩，递归最后返回的是根节点
        dis[x] = (dis[x] + dis[t]); // 权值更新为 x 到根节点的权值
    }
    return p[x];
}



int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i) p[i]=i;
    while(k--)
    {
        int a,x,y;scanf("%d%d%d",&a,&x,&y);
        if(x>n||y>n) ++ans;
        else
        {
            int px=find(x),py=find(y);
            if(a==1)
            {
                if(px==py&&(dis[x]-dis[y])%3) ++ans;
                else if(px!=py)
                {
                    p[px]=py;
                    dis[px]=dis[y]-dis[x];
                }
            }
            else
            {
                if(px==py&&(dis[x]-dis[y]-1)%3) ++ans;
                else if(px!=py)
                {
                    p[px]=py;
                    dis[px]=dis[y]-dis[x]+1;
                }
            }
        }
    }
    printf("%d",ans);
    return 0;
}